package com.greet.service.impl;

import com.greet.comparable.OrderDetailTopItemCmp;
import com.greet.entity.Orders;
import com.greet.mapper.OrderDetailMapper;
import com.greet.mapper.OrdersMapper;
import com.greet.mapper.UserMapper;
import com.greet.service.ReportService;
import com.greet.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

@Service
@Slf4j
public class ReportServiceImpl implements ReportService {
    @Autowired
    private OrdersMapper ordersMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private OrderDetailMapper orderDetailMapper;


    @Override
    public TurnoverReportVO turnoverStatistics(LocalDate begin, LocalDate end) {
        TurnoverReportVO turnoverReportVO;
        if (begin.isEqual(end)){//如果只有一天，进行时段统计
            turnoverReportVO = turnoverStatisticsOnceDays(begin);
        }
        else {//如果有多个天，进行每天的统计
            turnoverReportVO = turnoverStatisticsMultipleDays(begin, end);
        }
        return turnoverReportVO;
    }

    @Override
    public UserReportVO userStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = new ArrayList<>();
        List<Integer> newUserCountList = new ArrayList<>();

        //计算每天的新增用户
        while (!begin.isAfter(end)){
            LocalDateTime startTime = LocalDateTime.of(begin, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(begin, LocalTime.MAX);
            Integer currNewUserCount = userMapper.countUser(startTime, endTime);
            if (currNewUserCount == null) currNewUserCount = 0;

            newUserCountList.add(currNewUserCount);
            dateList.add(begin);

            begin = begin.plusDays(1L);
        }

        //计算每天为止的总用户
        Integer[] userCountList = new Integer[newUserCountList.size() + 1];
        Integer countAllUser = userMapper.countUser(
                LocalDateTime.of(2000, 1, 1, 0, 0, 0),
                LocalDateTime.of(begin, LocalTime.MAX));
        if (countAllUser == null)countAllUser = 0;
        for (int index = newUserCountList.size() - 1; index >= 0; --index){
            userCountList[index] = countAllUser;
            countAllUser = countAllUser - newUserCountList.get(index);
        }

        String dateListStr = StringUtils.join(dateList, ",");
        String newCntListStr = StringUtils.join(newUserCountList, ",");
        String cntListStr = StringUtils.join(userCountList, ",");

        UserReportVO reportVO = new UserReportVO(dateListStr, cntListStr, newCntListStr);
        return reportVO;
    }

    @Override
    public OrderReportVO ordersStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = new ArrayList<>();
        List<Integer> orderCountList = new ArrayList<>();
        List<Integer> validOrderCountList = new ArrayList<>();
        Integer totalOrderCount = 0;
        Integer validOrderCount = 0;

        while (!begin.isAfter(end)){
            LocalDateTime startTime = LocalDateTime.of(begin, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(begin, LocalTime.MAX);
            Integer orderCount = ordersMapper.count(startTime, endTime, null);
            Integer validCount = ordersMapper.count(startTime, endTime, Orders.COMPLETED);

            dateList.add(begin);
            orderCountList.add(orderCount);
            validOrderCountList.add(validCount);
            totalOrderCount += orderCount;
            validOrderCount += validCount;

            begin = begin.plusDays(1L);
        }

        Double orderCompletionRate = validOrderCount.doubleValue() / totalOrderCount.doubleValue();

        String dateListStr = StringUtils.join(dateList, ",");
        String orderCountListStr = StringUtils.join(orderCountList, ",");
        String validOrderCountStr = StringUtils.join(validOrderCountList, ",");

        OrderReportVO reportVO = OrderReportVO.builder()
                .totalOrderCount(totalOrderCount)
                .validOrderCount(validOrderCount)
                .dateList(dateListStr)
                .orderCountList(orderCountListStr)
                .validOrderCountList(validOrderCountStr)
                .orderCompletionRate(orderCompletionRate).build();

        return reportVO;
    }

    @Override
    public SalesTop10ReportVO top10(LocalDate begin, LocalDate end) {
        LocalDateTime startTime = LocalDateTime.of(begin, LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(end, LocalTime.MAX);
        List<Long> orderIds = ordersMapper.selectByTimeForId(startTime, endTime, Orders.COMPLETED);

        List<OrderDetailTopItem> orderDetailTopItems = orderDetailMapper.countSalesDish( 10, orderIds);
        List<OrderDetailTopItem> orderDetailTopItemsSetmeal = orderDetailMapper.countSalesSetmeal(10, orderIds);
        orderDetailTopItems.addAll(orderDetailTopItemsSetmeal);
        //如果当天没有销量， 返回空
        if (orderDetailTopItems == null || orderDetailTopItems.isEmpty()){
            return null;
        }
        orderDetailTopItems.sort(new OrderDetailTopItemCmp());

        String nameList = new String("");
        String numberList = new String("");

        int endIndex = 10 > orderDetailTopItems.size() ? orderDetailTopItems.size() : 10;
        for (int i = 0; i < endIndex; ++i){
            if (i != 0){
                nameList += ",";
                numberList += ",";
            }
            OrderDetailTopItem item = orderDetailTopItems.get(i);
            nameList += item.getName();
            numberList += item.getSalesVolume();
        }
        SalesTop10ReportVO reportVO = new SalesTop10ReportVO(nameList, numberList);
        return reportVO;
    }

    private TurnoverReportVO turnoverStatisticsOnceDays(LocalDate begin) {
        List<String> timeList = new ArrayList<>();
        //存放每个日期的营业额
        List<Double> turnoverList = new ArrayList<>();
        LocalDateTime todayEnd = LocalDateTime.of(begin, LocalTime.MAX);
        LocalDateTime startTime = LocalDateTime.of(begin, LocalTime.MIN);
        LocalDateTime endTime = startTime.plusHours(1L);
        while (!endTime.isAfter(todayEnd)){
            //分时段
            List<LocalTime> times = new ArrayList<>(3);
            times.add(startTime.toLocalTime());
            times.add(endTime.toLocalTime());
            String timeItem = StringUtils.join(times, "~");
            timeList.add(timeItem);

            //查询营业额
            BigDecimal summed = ordersMapper.sumTurnoverByDate(startTime, endTime);
            if (summed == null)turnoverList.add(0.0);
            else turnoverList.add(summed.doubleValue());
            //自增
            startTime = startTime.plusHours(1L);
            endTime = endTime.plusHours(1L);
        }
        //返回数据
        String timeListString = StringUtils.join(timeList, ",");
        String turnoverListString = StringUtils.join(turnoverList, ",");
        TurnoverReportVO reportVO = new TurnoverReportVO(timeListString, turnoverListString);
        return reportVO;
    }

    private TurnoverReportVO turnoverStatisticsMultipleDays(LocalDate begin, LocalDate end) {
        //存放begin到end范围内的每个日期
        List<LocalDate> dateList = new ArrayList<>();
        //存放每个日期的营业额
        List<Double> turnoverList = new ArrayList<>();

        for (LocalDate currDay = begin.plusDays(0L); !currDay.isAfter(end); currDay = currDay.plusDays(1L)){
            dateList.add(currDay.plusDays(0L));
            //查询状态为已完成的订单
            LocalDateTime beginTime = LocalDateTime.of(currDay, LocalTime.MIN);
            LocalDateTime endTime =  LocalDateTime.of(currDay, LocalTime.MAX);
            BigDecimal turnover = ordersMapper.sumTurnoverByDate(beginTime, endTime);
            if (turnover == null)turnoverList.add(0.0);
            else turnoverList.add(turnover.doubleValue());
        }

        String dateListString = StringUtils.join(dateList, ",");
        String turnoverListString = StringUtils.join(turnoverList, ",");

        TurnoverReportVO turnoverReportVO = new TurnoverReportVO(dateListString, turnoverListString);
        return turnoverReportVO;
    }
}
